#include "log_api.h"
#include "ota_api.h"
#include "rfid_app.h"
#include "event_app.h"
#include "basic_app.h"
#include "sound_app.h"
#include "ml307_app.h"
#include "safety_app.h"
#include "memroy_app.h"
#include "tp1107_app.h"
#include "gtx31x_app.h"
#include "flash_board.h"
#include "battery_app.h"
#include "network_app.h"
#include "protocol_api.h"
#include "real_time_app.h"
#include "bluetooth_app.h"
#include "protocol_board.h"
#include "cardholder_api.h"
#include "temporary_file.h"
#include "device_parameter.h"
#include "flash_api.h"
#include "rs485_app.h"

/**
 * @brief 消息中心任务处理回调
 *
 */
static uint16_t ProtocolCenterTaskCallback(uint8_t TaskId, uint16_t Events);

static uint8_t ProtocolCenterTaskHandle = 0;
static ProtocolCenterExternalInterfaces_t ProtocolCenterExternalInterfaces = {0};

static uint16_t ProtocolCenterTaskCallback(uint8_t TaskId, uint16_t Events)
{
  if (TaskId == ProtocolCenterTaskHandle)
  {
    if (Events & SYS_EVENT_MSG)
    {
      uint8_t *pProtocol = tmos_msg_receive(ProtocolCenterTaskHandle);
      if (pProtocol != NULL)
      {
        if (ProtocolCenterExternalInterfaces.ProtocolParsingTask != NULL)
        {
          ProtocolCenterExternalInterfaces.ProtocolParsingTask(pProtocol);
        }

        tmos_msg_deallocate(pProtocol);
      }

      return (Events ^ SYS_EVENT_MSG);
    }

    if (Events & MESSAGE_CENTER_SENDING)
    {
      if (ProtocolCenterExternalInterfaces.ProtocolSendingTask != NULL)
      {
        ProtocolCenterExternalInterfaces.ProtocolSendingTask();
      }

      return (Events ^ MESSAGE_CENTER_SENDING);
    }
  }

  return 0;
}

//用作存储io板固件的临时文件
uint32_t ProtocolGetMaxCacheFileSize(void)
{
  // return FLASH_TEMPORARY_FILE_ACTUAL_OCCUPIED_SPACE;
  return IO_BOARD_FIRMWARE_ACTUAL_OCCUPIED_SPACE;
}

static uint32_t s_FileSumSize = 0;

uint32_t ProtocolGetFileSumSize(void)
{
  return s_FileSumSize;
}

bool ProtocolSetFileSumSize(uint32_t FileSumSize){
  s_FileSumSize = FileSumSize;
  return true;
}


bool ProtocolGetExternalValidationFunctionEnableBit(void)
{
  return _EXTERNAL_VALIDATION_EN_;
}

uint32_t ProtocolGetCurrentTimestamp(void)
{
  return RealTimeMakeCurrentTimestamp();
}

bool ProtocolSetCurrentTimestamp(uint32_t Timestamp)
{
  uint32_t TmpTimestamp = 0;

  memset(&TmpTimestamp, PROTOCOL_ENQUIRY_FLAG, 4);
  if (TmpTimestamp == Timestamp)
    return true;

  if (RealTimeTimestampToRtc(Timestamp) == true)
    return true;

  return false;
}

bool ProtocolGetMessageQueueBusyEn(void)
{
  return EventGetMessageQueueBusyFlagBit();
}

void ProtocolSetMessageQueueBusyEn(bool En)
{
  EventSetMessageQueueBusyFlagBit(En);
}

ProtocolNetAttaResult_t ProtocolGetNetworkAttachmentStatus(void)
{
  ProtocolNetAttaResult_t Result = NETWORK_NOT_ACTIVATED;
  uint8_t ConnectStatus = EventGetNetworkConnectStatus();

  switch (ConnectStatus)
  {
  case NETWORK_CONNECT_ERROR:
    Result = NETWORK_ATTACHMENT_ERROR;
    break;

  case NETWORK_CONNECT_SUCCESS:
    Result = NETWORK_ATTACHMENT_SUCCESS;
    break;

  case NETWORK_LINKS_BEING_ESTABLISHED:
    Result = NETWORK_ATTACHMENT_ACCESS;
    break;
  }

  return Result;
}

uint8_t ProtocolGetLocalRegisterStep(void)
{
  return EventGetLocalRegisterKeyStep();
}

uint8_t ProtocolGetLocalRegisterResult(void)
{
  return EventGetLocalRegisterKeyResult();
}

void ProtocolMarkFileCheckCodeFailure(void)
{
  EventExitOnlineRegisterTask(0, NULL, 0);
  EventUpdateOnlineRegisterResult(REGISTER_USER_FILE_ERROR);
}

bool ProtocolIntoOnlineRegisterMode(uint8_t FileType, uint32_t FileSize, const void *pRegisterUsersThroughFilesIn)
{
  OnlineRegisterInformation_t OnlineRegisterInformation = {0};
  RegisterUsersThroughFilesFormat_t *pRegisterUsersThroughFilesFormat = (RegisterUsersThroughFilesFormat_t *)pRegisterUsersThroughFilesIn;

  OnlineRegisterInformation.FileSize = FileSize;
  OnlineRegisterInformation.Source = pRegisterUsersThroughFilesFormat->Source;
  OnlineRegisterInformation.CheckCode = pRegisterUsersThroughFilesFormat->CheckCode;
  OnlineRegisterInformation.NumberOfRemainingFile = pRegisterUsersThroughFilesFormat->NumberOfRemainingFile;

  OnlineRegisterInformation.KeyInformation.Count = pRegisterUsersThroughFilesFormat->Count;
  OnlineRegisterInformation.KeyInformation.KeyToken = pRegisterUsersThroughFilesFormat->KeyToken;
  OnlineRegisterInformation.KeyInformation.AuthenticationType = (FileType == FILE_FACE_EIGENVALUE) ? FACE_ID_AUTHENTICATION : FINGER_PRINTF_AUTHENTICATION;
  memcpy(OnlineRegisterInformation.KeyInformation.UserName, pRegisterUsersThroughFilesFormat->UserName, USER_NAME_LENGTH);

  OnlineRegisterInformation.KeyInformation.Date = pRegisterUsersThroughFilesFormat->Date;
  OnlineRegisterInformation.KeyInformation.EndTimestamp = pRegisterUsersThroughFilesFormat->EndTimestamp;
  OnlineRegisterInformation.KeyInformation.StartTimestamp = pRegisterUsersThroughFilesFormat->StartTimestamp;
  for (uint8_t i = 0; i < MAX_TIME_SLOTS; i++)
  {
    OnlineRegisterInformation.KeyInformation.StartHour[i] = pRegisterUsersThroughFilesFormat->TimePeriod[i].StartHour;
    OnlineRegisterInformation.KeyInformation.StartMinute[i] = pRegisterUsersThroughFilesFormat->TimePeriod[i].StartMinute;
    OnlineRegisterInformation.KeyInformation.EndHour[i] = pRegisterUsersThroughFilesFormat->TimePeriod[i].EndHour;
    OnlineRegisterInformation.KeyInformation.EndMinute[i] = pRegisterUsersThroughFilesFormat->TimePeriod[i].EndMinute;
  }

  return EventStartOnlineRegisterTask(&OnlineRegisterInformation);
}

uint8_t ProtocolCheckFileValidity(uint32_t FileSize)
{
  return CalculateTemporaryFileCheckCode(FileSize);
}

uint16_t ProtocolGetRfidFailureIdent(void)
{
  uint16_t Ident = 0, FaultyIdent = 0;

  FaultyIdent = EventGetRfidCommunicationFaultyIdent();
  switch (FaultyIdent)
  {
  case DEV_SELF_TEST_SUCCESS:
    Ident = SELF_TEST_RESULT_SUCCESS;
    break;

  case DEV_SELF_TEST_NO_SUPPORT:
    Ident = SELF_TEST_RESULT_NO_SUPPORT;
    break;

  default:
    Ident = SELF_TEST_RESULT_ERROR;
    break;
  }

  return Ident;
}

uint16_t ProtocolGetKeyboardFailureIdent(void)
{
  uint16_t Ident = 0, FaultyIdent = 0;

  FaultyIdent = EventGetKeyboardCommunicationFaultyIdent();
  switch (FaultyIdent)
  {
  case DEV_SELF_TEST_SUCCESS:
    Ident = SELF_TEST_RESULT_SUCCESS;
    break;

  case DEV_SELF_TEST_NO_SUPPORT:
    Ident = SELF_TEST_RESULT_NO_SUPPORT;
    break;

  default:
    Ident = SELF_TEST_RESULT_ERROR;
    break;
  }

  return Ident;
}

uint16_t ProtocolGetFaceFailureIdent(void)
{
  uint16_t Ident = SELF_TEST_RESULT_NO_SUPPORT;

  uint16_t FaultyIdent = EventGetSafetyModuleCommunicationFaultyIdent();
  switch (FaultyIdent)
  {
  case DEV_SELF_TEST_SUCCESS:
    Ident = SELF_TEST_RESULT_SUCCESS;
    break;

  case DEV_SELF_TEST_NO_SUPPORT:
    Ident = SELF_TEST_RESULT_NO_SUPPORT;
    break;

  default:
    Ident = SELF_TEST_RESULT_ERROR;
    break;
  }

  return Ident;
}

uint16_t ProtocolGetFingerFailureIdent(void)
{
  uint16_t Ident = 0;

  uint16_t FaultyIdent = EventGetSafetyModuleCommunicationFaultyIdent();
  switch (FaultyIdent)
  {
  case DEV_SELF_TEST_SUCCESS:
    Ident = SELF_TEST_RESULT_SUCCESS;
    break;

  case DEV_SELF_TEST_NO_SUPPORT:
    Ident = SELF_TEST_RESULT_NO_SUPPORT;
    break;

  default:
    Ident = SELF_TEST_RESULT_ERROR;
    break;
  }

  return Ident;
}

uint16_t ProtocolGetWirelessFailureIdent(void)
{
  uint16_t Ident = DEV_SELF_TEST_NO_SUPPORT;

  uint16_t FaultyIdent = EventGetNetworkCommunicationFaultyIdent();
  switch (FaultyIdent)
  {
  case DEV_SELF_TEST_SUCCESS:
    Ident = SELF_TEST_RESULT_SUCCESS;
    break;

  case DEV_SELF_TEST_NO_SUPPORT:
    Ident = SELF_TEST_RESULT_NO_SUPPORT;
    break;

  default:
    Ident = SELF_TEST_RESULT_ERROR;
    break;
  }

  return Ident;
}

uint8_t ProtocolGetSelfTestResult(void)
{
  uint8_t SelfTestResult = SELF_CHECK_BUSY;
  SelfTestOrder_t SelfTestOrder = EventGetSelfTestResult();

  switch (SelfTestOrder)
  {
  case SELF_TEST_WAIT:
    SelfTestResult = SELF_CHECK_IDLE;
    break;

  case ALL_MODULE_SELF_TEST_SUCCESS:
    SelfTestResult = SELF_CHECK_DONE;
    break;

  default:
    break;
  }

  return SelfTestResult;
}

uint8_t ProtocolGetVoltagePercentage(void)
{
  return BatteryGetVoltagePercentage();
}

void ProtocolGetDeviceMacAddr(uint8_t *pMacAddrOut)
{
  uint8_t MacAddr[MAC_ADDR_CODING_LENGTH] = {0};

  if (pMacAddrOut != NULL)
  {
    GetMACAddress(MacAddr);
    for (uint8_t i = 0; i < MAC_ADDR_CODING_LENGTH; i++)
    {
      pMacAddrOut[i] = MacAddr[(MAC_ADDR_CODING_LENGTH - 1) - i];
    }
  }
}

bool ProtocolGetRs485FunctionEnableBit(void)
{
  if (_NETWOK_FUNCTION_ENABLE_)
  {
    if (_NETWOK_MODLE_TYPE_ == _RS485_MODULE_)
      return true;
  }

  return false;
}

bool ProtocolNetworkFunctionEnableBit(void)
{
  if (_NETWOK_FUNCTION_ENABLE_)
    return true;

  return false;
}

bool ProtocolGetFaceFunctionEnableBit(void)
{
  if (_SAFETY_VERIFYFUNCTION_ENABLE_)
  {
    if (_SAFETY_MODULE_TYPE_ == _FACE_SAFETY_MODULE_)
      return true;
  }

  return false;
}

bool ProtocolGetDirectoryOfAvailableCardholders(const uint8_t *pUserNameIn)
{
  CardholderInformation_t CardholderInformation = {0};

  if (pUserNameIn != NULL)
  {
    if (FindCardholder(pUserNameIn, NULL, &CardholderInformation) == true)
    {
      if (CardholderInformation.UserInformation.NumberOfKey < MAX_NUMBER_OF_KEYS_CARRIED_BY_SINGLE_USER)
        return true;
    }
    else
    {
      if (FindEmptyCardholderCatalogues(NULL) == true)
        return true;
    }
  }

  return false;
}

bool ProtocolDetermineIfThisTypeOfKeySupportsLocalRegister(uint8_t KeyType)
{
  bool Result = false;

  switch (KeyType)
  {
  case CARD_AUTHENTICATION:
  {
    if (_RFID_FUNCTION_ENABLE_)
      return true;
  }
  break;

  case PASSWORD_AUTHENTICATION:
  {
    if (_KEYBOARD_FUNCTION_ENABLE_)
      return true;
  }
  break;

  case FINGER_PRINTF_AUTHENTICATION:
  {
    if (_SAFETY_VERIFYFUNCTION_ENABLE_)
      return true;
  }
  break;

  case FACE_ID_AUTHENTICATION:
  {
    if (_SAFETY_VERIFYFUNCTION_ENABLE_)
      return true;
  }
  break;
  }

  return false;
}

uint8_t ProtocolGetDeviceFunction(void)
{
  return GetOnboardFunctionsInBatches();
}

bool ProtocolSetDeviceFunction(uint8_t Function)
{
  if (Function == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetOnboardFunctionsInBatches(Function) == true)
    return true;

  return false;
}

bool ProtocolGetDeviceActivationStatus(void)
{
  uint8_t WorkMode = GetDeviceInitStatus() & (~FIRMWARE_UPGRADE);
  if (WorkMode == NORMAL_MODE)
    return true;

  return false;
}

bool ProtocolGetBootloaderUpdateInfo(uint32_t *pCrcValue, uint32_t *pFileSize)
{
  return EventGetFirmwareDataInformation(pCrcValue, pFileSize);
}

void ProtocolIntoNormalMode(void)
{
  SetDeviceInitStatus(NORMAL_MODE);
}

void ProtocolIntoBootloaderFirmwareUpdateMode(uint32_t CrcValue, uint32_t FileSize)
{
  EventStartBootloaderUpdateTask(CrcValue, FileSize);
}

void ProtocolExitBootloaderFirmwareUpdateMode(bool UpdateStatus)
{
  FirmwareUpdateStatus_t FirmwareUpdateStatus = (UpdateStatus == true) ? FIRMWARE_UPDATE_STATUS_SUCCESS : FIRMWARE_UPDATE_STATUS_ERROR;
  EventExitBootloaderUpdateTask(FirmwareUpdateStatus);
}

void ProtocolIntoApplicationFirmwareUpdateMode(void)
{
  uint8_t DeviceStatus = GetDeviceInitStatus();
  SetDeviceInitStatus(DeviceStatus | FIRMWARE_UPGRADE);
  ProtocolUpdateDeviceParamete();

  EventStartApplicationUpdateTask();
}

bool ProtocolGetNormalOpenEn(void)
{
  return GetNormalOpenEn();
}

uint8_t ProtocolGetDeviceType(void)
{
  return GetObtainTheDeviceModel();
}

bool ProtocolSetDeviceType(uint8_t DeviceType)
{
  if (DeviceType == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetObtainTheDeviceModel(DeviceType) == true)
    return true;

  return false;
}

uint32_t ProtocolGetDateOfProduction(void)
{
  return ObtainTheDeliveryDateOfTheDevice();
}

bool ProtocolSetDateOfProduction(uint32_t Date)
{
  uint32_t DateOfProduction = 0;

  memset(&DateOfProduction, PROTOCOL_ENQUIRY_FLAG, 4);
  if (Date == DateOfProduction)
    return true;

  if (SetTheDeviceDeliveryDate(Date) == true)
    return true;

  return false;
}

void ProtocolGetBoardVersionNumber(void *pBoardVersionOut)
{
  if (pBoardVersionOut != NULL)
  {
    ObtainCircuitBoardModel(pBoardVersionOut);
  }
}

bool ProtocolSetBoardVersionNumber(const void *pBoardVersionIn)
{
  char *pBoardVersion = (char *)pBoardVersionIn;
  char PcbVersion[NUMBER_OF_FIRMWARE_VERSION] = {0};

  if (pBoardVersionIn != NULL)
  {
    memset(PcbVersion, PROTOCOL_ENQUIRY_FLAG, NUMBER_OF_FIRMWARE_VERSION);
    if (memcmp(pBoardVersion, PcbVersion, NUMBER_OF_FIRMWARE_VERSION) == 0)
      return true;

    if (strlen(pBoardVersion) <= NUMBER_OF_FIRMWARE_VERSION)
    {
      if (WriteCircuitBoardType(pBoardVersion) == true)
        return true;
    }
  }

  return false;
}

void ProtocolGetFirmwareVersionNumber(void *pFirmwareVersionOut)
{
  if (pFirmwareVersionOut != NULL)
  {
    GetDeviceFirmwareVersion(pFirmwareVersionOut);
  }
}

void ProtocolGetQualityControlCode(void *pQualityControlCodeOut)
{
  if (pQualityControlCodeOut != NULL)
  {
    GetQualityInspectorCode(pQualityControlCodeOut);
  }
}

bool ProtocolSetQualityControlCode(const void *pQualityControlCodeIn)
{
  char *pQualityControlCode = (char *)pQualityControlCodeIn;
  char QualityControlCode[NUMBER_OF_QC_CODE] = {0};

  if (pQualityControlCodeIn != NULL)
  {
    memset(QualityControlCode, PROTOCOL_ENQUIRY_FLAG, NUMBER_OF_QC_CODE);
    if (memcmp(pQualityControlCode, QualityControlCode, NUMBER_OF_QC_CODE) == 0)
      return true;

    if (strlen(pQualityControlCode) <= NUMBER_OF_FIRMWARE_VERSION)
    {
      if (SetQualityInspectorCode(pQualityControlCode) == true)
        return true;
    }
  }

  return false;
}

void ProtocolGetChipModelNumber(void *pChipModelOut)
{
  GetChipModel(pChipModelOut);
}

uint8_t ProtocolGetNumberOfCardholder(void)
{
  return GetNumberOfCardholder();
}

bool ProtocolSetNumberOfCardholder(uint8_t NumberOfCardholder)
{
  if (NumberOfCardholder == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetNumberOfCardholder(NumberOfCardholder))
    return true;

  return false;
}

bool ProtocolGetDayBroadcastContorlEn(void)
{
  if (GetDayBroadcastContorlEn() == true)
    return true;

  return false;
}

bool ProtocolSetDayBroadcastContorlEn(uint8_t ContorlEn)
{
  if (ContorlEn == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetDayBroadcastContorlEn(ContorlEn) == true)
    return true;

  return false;
}

uint8_t ProtocolGetBroadcastRemainingDays(void)
{
  return GetBroadcastRemainingDays();
}

bool ProtocolSetBroadcastRemainingDays(uint8_t RemainingDays)
{
  if (RemainingDays == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetBroadcastRemainingDays(RemainingDays) == true)
    return true;

  return false;
}

uint8_t ProtocolGetSystemVolume(void)
{
  return GetSystemVolumeLevel();
}

bool ProtocolSetSystemVolume(uint8_t Volume)
{
  if (Volume == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetSystemVolumeLevel(Volume) == true)
    return true;

  return false;
}

uint8_t ProtocolGetElevatorId(void)
{
  return GetElevatorId();
}

bool ProtocolSetElevatorId(uint8_t ElevatorId)
{
  SetElevatorId(ElevatorId);
  return true;
}

bool ProtocolSetPublicFloorData(uint8_t* Data)
{
  return SetPublicFloorData(Data);
}

bool ProtocolGetPublicFloorData(uint8_t* Data)
{
  return GetPublicFloorData(Data);
}

bool ProtocolSetDestinMacAddress(uint8_t *pDestinMacAddr)
{
  SetDestinMacAddress(pDestinMacAddr);
  return true;
}

uint8_t ProtocolGetElevatorStartFloor(void)
{
  return GetElevatorStartFloor();
}

bool ProtocolSetElevatorStartFloor(uint8_t StartFloor)
{
  SetElevatorStartFloor(StartFloor);
  return true;
}

//todo: 完成
bool ProtocolGetReadCardSectorKey(uint8_t* SectorKey)
{
  if (SectorKey != NULL)
  {
    GetElevatorCardOperationSectorKey(SectorKey);//梯控扇区密钥
    return true;
  }
  return false;
}

//todo: 完成
bool ProtocolSetReadCardSectorKey(uint8_t* SectorKey)
{
  return SetElevatorCardOperationSectorKey(SectorKey);//梯控扇区密钥
}

//todo: 完成
bool ProtocolSetReadCardStartSectorId(uint8_t SectorId)
{
  return SetElevatorCardOperationSector(SectorId);//梯控扇区id
}

//todo: 完成
uint8_t ProtocolGetReadCardStartSectorId(void)
{
  return GetElevatorCardOperationSector();//梯控扇区id
}

uint8_t ProtocolGetUnlockingTime(void)
{
  return GetUnlockTime();
}

bool ProtocolSetUnlockingTime(uint8_t UnlockingTime)
{
  if (UnlockingTime == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetUnlockTime(UnlockingTime) == true)
    return true;

  return false;
}

uint8_t ProtocolGetMotorDriveTime(void)
{
  return GetMotorDriveTime();
}

bool ProtocolSetMotorDriveTime(uint8_t DriveTime)
{
  if (DriveTime == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetMotorDriveTime(DriveTime) == true)
    return true;

  return false;
}

uint16_t ProtocolGetHeartbeatInterval(void)
{
  return GetHeartbeatTransmissionCycle();
}

bool ProtocolSetHeartbeatInterval(uint16_t Heartbeat)
{
  uint16_t TmpHeartbeat = (PROTOCOL_ENQUIRY_FLAG << 8) | PROTOCOL_ENQUIRY_FLAG;
  if (Heartbeat == TmpHeartbeat)
    return true;

  if (SetHeartbeatTransmissionCycle(Heartbeat) == true)
    return true;

  return false;
}

uint8_t ProtocolGetCameraRecognitionTimeout(void)
{
  return GetSearchTimeout();
}

bool ProtocolSetCameraRecognitionTimeout(uint8_t SearchTimeout)
{
  if (SearchTimeout == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetSearchTimeout(SearchTimeout) == true)
    return true;

  return false;
}

uint8_t ProtocolGetAllowableTimeError(void)
{
  return GetAllowableTimeError();
}

bool ProtocolSetAllowableTimeError(uint8_t ErrorTime)
{
  if (ErrorTime == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetAllowableTimeError(ErrorTime) == true)
    return true;

  return false;
}

uint8_t ProtocolGetKeyboardSensitivity(void)
{
  return GetKeyboardSensitivity();
}

bool ProtocolSetKeyboardSensitivity(uint8_t Sensitivity)
{
  if (Sensitivity == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetKeyboardSensitivity(Sensitivity) == true)
    return true;

  return false;
}

uint8_t ProtocolGetOfflineCardFunctionEnable(void)
{
  return GetOfflineCardFunctionEnable();
}

bool ProtocolSetOfflineCardFunctionEnable(uint8_t Enable)
{
  if (Enable == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetOfflineCardFunctionEnable(Enable) == true)
    return true;

  return false;
}

uint8_t ProtocolGetAcquireNetworkOperators(void)
{
  return GetNetworkOperator();
}

bool ProtocolSetAcquireNetworkOperators(uint8_t NetworkOperator)
{
  if (NetworkOperator == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetNetworkOperator(NetworkOperator) == true)
    return true;

  return false;
}

uint8_t ProtocolGetBluetoothConnectionTimeout(void)
{
  return GetBluetoothConnectionTimeout();
}

bool ProtocolSetBluetoothConnectionTimeout(uint8_t Timeout)
{
  if (Timeout == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetBluetoothConnectionTimeout(Timeout) == true)
    return true;

  return false;
}

uint8_t ProtocolGetFalseLockDetcetionInterval(void)
{
  return GetFalseLockDetcetionInterval();
}

bool ProtocolSetFalseLockDetcetionInterval(uint8_t Interval)
{
  if (Interval == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetFalseLockDetcetionInterval(Interval) == true)
    return true;
  return false;
}

uint8_t ProtocolGetTheBreakInDetcetionInterval(void)
{
  return GetTheBreakInDetcetionInterval();
}

bool ProtocolSetBreakInDetcetionInterval(uint8_t Interval)
{
  if (Interval == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetBreakInDetcetionInterval(Interval) == true)
    return true;

  return false;
}

uint8_t ProtocolGetNormalOpenReminderInterval(void)
{
  return GetNormalOpenReminderInterval();
}

bool ProtocolSetNormalOpenReminderInterval(uint8_t Interval)
{
  if (Interval == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetNormalOpenReminderInterval(Interval) == true)
    return true;

  return false;
}

uint8_t ProtocolGetErrorPromptFunctionConfiguration(void)
{
  return GetErrorPromptFunctionConfiguration();
}

bool ProtocolSetErrorPromptFunctionConfiguration(uint8_t Configuration)
{
  if (Configuration == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetErrorPromptFunctionConfiguration(Configuration) == true)
    return true;

  return false;
}

uint8_t ProtocolGetBluetoothUpdateRaidioInterval(void)
{
  return GetBluetoothUpdateRaidioInterval();
}

bool ProtocolSetBluetoothUpdateRaidioInterval(uint8_t Interval)
{
  if (Interval == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetBluetoothUpdateRaidioInterval(Interval) == true)
    return true;

  return false;
}

uint8_t ProtocolGetLockedInReminderInterval(void)
{
  return GetLockedInReminderInterval();
}

bool ProtocolSetLockedInReminderInterval(uint8_t Interval)
{
  if (Interval == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetLockedInReminderInterval(Interval) == true)
    return true;

  return false;
}

uint8_t ProtocolGetCardReadingSensitivity(void)
{
  return GetCardReadingSensitivity();
}

bool ProtocolSetCardReadingSensitivity(uint8_t Sensitivity)
{
  if (Sensitivity == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetCardReadingSensitivity(Sensitivity) == true)
    return true;

  return false;
}

uint8_t ProtocolGetReadTheCardType(void)
{
  return GetReadTheCardType();
}

bool ProtocolSetReadTheCardType(uint8_t CardType)
{
  if (CardType == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetReadTheCardType(CardType) == true)
    return true;

  return false;
}

void ProtocolGetCardOperationSectorKey(uint8_t *pKeyOut)
{
  GetCardOperationSectorKey(pKeyOut);
}

bool ProtocolSetCardOperationSectorKey(const uint8_t *pKeyIn)
{
  if (pKeyIn != NULL)
  {
    uint8_t KeyValue[CRAD_SECTOR_KEY_LENGTH] = {0};

    memset(KeyValue, PROTOCOL_ENQUIRY_FLAG, CRAD_SECTOR_KEY_LENGTH);
    if (memcmp(pKeyIn, KeyValue, CRAD_SECTOR_KEY_LENGTH) == true)
      return true;

    return SetCardOperationSectorKey(pKeyIn);
  }

  return false;
}

uint8_t ProtocolGetCardOperationSector(void)
{
  return GetCardOperationSector();
}

bool ProtocolSetCardOperationSector(uint8_t StartSector)
{
  if (StartSector == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetCardOperationSector(StartSector) == true)
    return true;

  return false;
}

uint32_t ProtocolGetCustomerCode(void)
{
  return GetCustomerCode();
}

bool ProtocolSetCustomerCode(uint32_t CustomerCode)
{
  uint32_t UserCode = 0;

  memset(&UserCode, PROTOCOL_ENQUIRY_FLAG, 4);
  if (CustomerCode == UserCode)
    return true;

  if (SetCustomerCode(CustomerCode) == true)
    return true;

  return false;
}

uint32_t ProtocolGetAuthorizationEndTime(void)
{
  return GetAuthorizationEndTime();
}

bool ProtocolSetAuthorizationEndTime(uint32_t EndTime)
{
  uint32_t Time = 0;

  memset(&Time, PROTOCOL_ENQUIRY_FLAG, 4);
  if (EndTime == Time)
    return true;

  if (SetAuthorizationEndTime(EndTime) == true)
    return true;

  return false;
}

void ProtocolGetEncryptionKey(void *pEncryptionKeyOut)
{
  GetEncryptionKey(pEncryptionKeyOut);
}

bool ProtocolSetEncryptionKey(const void *pEncryptionKeyIn)
{
  if (pEncryptionKeyIn != NULL)
  {
    uint8_t KeyValue[ENCRYPTION_KEY_LENGTH] = {0};

    memset(KeyValue, PROTOCOL_ENQUIRY_FLAG, ENCRYPTION_KEY_LENGTH);
    if (memcmp(pEncryptionKeyIn, KeyValue, ENCRYPTION_KEY_LENGTH) == true)
      return true;

    return SetEncryptionKey(pEncryptionKeyIn);
  }

  return false;
}

void ProtocolGetSuperAdministratorPassword(void *pPasswordOut)
{
  GetSuperAdministratorPassword(pPasswordOut);
}

bool ProtocolSetSuperAdministratorPassword(const void *pPasswordIn)
{
  if (pPasswordIn != NULL)
  {
    uint8_t Password[NUMBER_OF_KEYBOARD_KEY] = {0};

    memset(Password, PROTOCOL_ENQUIRY_FLAG, NUMBER_OF_KEYBOARD_KEY);
    if (memcmp(pPasswordIn, Password, NUMBER_OF_KEYBOARD_KEY) == true)
      return true;

    return SetSuperAdministratorPassword(pPasswordIn);
  }

  return false;
}

uint8_t ProtocolGetTimeZone(void)
{
  return GetSystemTimeZone();
}

bool ProtocolSetTimeZone(uint8_t TimeZone)
{
  if (TimeZone == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetSystemTimeZone(TimeZone))
    return true;

  return false;
}

uint16_t ProtocolGetRoomType(void)
{
  return GetRoomType();
}

bool ProtocolSetRoomType(uint16_t RoomType)
{
  return SetRoomType(RoomType);
}

uint32_t ProtocolGetGroupingNumber(void)
{
  return GetGroupingNumber();
}

bool ProtocolSetGroupingNumber(uint32_t GroupingNumber)
{
  return SetGroupingNumber(GroupingNumber);
}

uint8_t ProtocolGetParkNumber(void)
{
  return GetLockGardenIdNumber();
}

bool ProtocolSetParkNumber(uint8_t ParkId)
{
  if (ParkId == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetLockGardenIdNumber(ParkId) == true)
    return true;

  return false;
}

uint8_t ProtocolGetBuildingNumber(void)
{
  return GetLockBuildingNumber();
}

bool ProtocolSetBuildingNumber(uint8_t BuildingId)
{
  if (BuildingId == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetLockBuildingNumber(BuildingId) == true)
    return true;

  return false;
}

uint8_t ProtocolGetFloorNumber(void)
{
  return GetLockFloorNumber();
}

bool ProtocolSetFloorNumber(uint8_t FloorId)
{
  if (FloorId == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetLockFloorNumber(FloorId) == true)
    return true;

  return false;
}

uint32_t ProtocolGetRoomNumber(void)
{
  return GetLockRoomIdNumber();
}

bool ProtocolSetRoomNumber(uint32_t RoomId)
{
  uint32_t RoomNumber = 0;

  memset(&RoomNumber, PROTOCOL_ENQUIRY_FLAG, 4);
  if (RoomNumber == RoomId)
    return true;

  if (SetLockRoomIdNumber(RoomId) == true)
    return true;

  return false;
}

uint8_t ProtocolGetChildRommNumber(void)
{
  return GetLockSubroomNumber();
}

bool ProtocolSetChildRommNumber(uint8_t ChildRommNumber)
{
  if (ChildRommNumber == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetLockSubroomNumber(ChildRommNumber) == true)
    return true;

  return false;
}

uint32_t ProtocolGetDeviceActivationTime(void)
{
  return GetDeviceLastActionTime();
}

void ProtocolSetDeviceActivationTime(uint32_t Time)
{
  SetDeviceLastActionTime(Time);
}

uint8_t ProtocolGetProtocolFormat(void)
{
  return GetProtocolFormat();
}

bool ProtocolSetProtocolFormat(uint8_t ProtocolFormat)
{
  if (ProtocolFormat == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (ProtocolGetDeviceActivationStatus() != true)
  {
    if (SetProtocolFormat(ProtocolFormat) == true)
      return true;
  }

  return false;
}

void ProtocolGetOuterLayerEncryptionKey(uint8_t *pKeyOut)
{
  if (pKeyOut != NULL)
  {
    if (ProtocolGetDeviceActivationStatus() == true)
    {
      switch (GetProtocolFormat())
      {
      case PROTOCOL_FORMAT_SMSZ:
        memcpy(pKeyOut, FIXED_ENCRYED_DECRYED_KEY_SMSZ, ENCRYPTION_KEY_LENGTH);
        break;

      case PROTOCOL_FORMAT_DL:
        memcpy(pKeyOut, FIXED_ENCRYED_DECRYED_KEY_DL, ENCRYPTION_KEY_LENGTH);
        break;

      default:
        memcpy(pKeyOut, FIXED_ENCRYED_DECRYED_KEY_YGS, ENCRYPTION_KEY_LENGTH);
        break;
      }
    }
    else
    {
      memcpy(pKeyOut, FIXED_ENCRYED_DECRYED_KEY_YGS, ENCRYPTION_KEY_LENGTH);
    }
  }
}

uint16_t ProtocolGetDeviceIndexMask(void)
{
  uint16_t DeviceIndexMask = PROTOCOL_DEVICE_INDEX_MASK_YGS;

  if (ProtocolGetDeviceActivationStatus() == true)
  {
    switch (GetProtocolFormat())
    {
    case PROTOCOL_FORMAT_SMSZ:
      DeviceIndexMask = PROTOCOL_DEVICE_INDEX_MASK_SMSZ;
      break;

    case PROTOCOL_FORMAT_DL:
      DeviceIndexMask = PROTOCOL_DEVICE_INDEX_MASK_DL;
      break;

    default:
      DeviceIndexMask = PROTOCOL_DEVICE_INDEX_MASK_YGS;
      break;
    }
  }

  return DeviceIndexMask;
}

bool ProtocolGetDnsServerAddress(void *pDnsAddressOut)
{
  if (pDnsAddressOut != NULL)
  {
    GetDnsServerAddress(pDnsAddressOut);
    return true;
  }

  return false;
}

bool ProtocolSetDnsServerAddress(const void *pDnsAddressIn)
{
  if (pDnsAddressIn != NULL)
  {
    uint8_t DnsAddress[NUMBER_OF_SERVER_IP_ADDRESS] = {0};

    memset(DnsAddress, PROTOCOL_DUMMY_CODING, NUMBER_OF_SERVER_IP_ADDRESS);
    if (memcmp(DnsAddress, pDnsAddressIn, NUMBER_OF_SERVER_IP_ADDRESS) == true)
      return true;

    if (SetDnsServerAddress(pDnsAddressIn) == true)
      return true;
  }

  return false;
}

void ProtocolObtainTheServerDomainAddress(void *pDomainAddressOut)
{
  if (pDomainAddressOut != NULL)
  {
    GetNetworkDomianName(pDomainAddressOut);
  }
}

bool ProtocolSetTheDomainNameOfTheServer(const void *pDomainAddressIn)
{
  char DomainAddress[NUMBER_OF_SERVER_DOMIAN_NAME_BIT] = {0};

  if (pDomainAddressIn != NULL)
  {
    memset(DomainAddress, PROTOCOL_DUMMY_CODING, NUMBER_OF_SERVER_DOMIAN_NAME_BIT);
    if (memcmp(DomainAddress, pDomainAddressIn, NUMBER_OF_SERVER_DOMIAN_NAME_BIT) == 0)
      return true;

    if (SetNetworkDomianName(pDomainAddressIn) == true)
      return true;
  }

  return false;
}

uint16_t ProtocolGetTheServerConnectionPort(void)
{
  uint16_t ConnectionPort = GetNetworkServerPort();
  return ConnectionPort;
}

bool ProtocolSetTheServerConnectionPort(uint16_t ConnectionPort)
{
  uint16_t TmpConnectionPort = 0;

  TmpConnectionPort = (PROTOCOL_DUMMY_CODING << 8) | PROTOCOL_DUMMY_CODING;
  if (ConnectionPort == TmpConnectionPort)
    return true;

  if (SetNetworkServerPort(ConnectionPort) == true)
    return true;

  return false;
}

void ProtocolGetMqttUserName(void *pUserNameOut)
{
  if (pUserNameOut != NULL)
  {
    GetMqttUserName(pUserNameOut);
  }
}

bool ProtocolSetMqttUserName(const void *pUserNameIn)
{
  char UserName[NUMBER_OF_MQTT_USER_NAME_BIT] = {0};

  if (pUserNameIn != NULL)
  {
    memset(UserName, PROTOCOL_DUMMY_CODING, NUMBER_OF_MQTT_USER_NAME_BIT);
    if (memcmp(UserName, pUserNameIn, NUMBER_OF_MQTT_USER_NAME_BIT) == 0)
      return true;

    if (SetMqttUserName(pUserNameIn) == true)
      return true;
  }

  return false;
}

void ProtocolGetMqttAccessPassword(void *pPasswordOut)
{
  if (pPasswordOut != NULL)
  {
    GetMqttPassword(pPasswordOut);
  }
}

bool ProtocolSetMqttAccessPassword(const void *pPasswordIn)
{
  char Password[NUMBER_OF_MQTT_PASSWORD_BIT] = {0};

  if (pPasswordIn != NULL)
  {
    memset(Password, PROTOCOL_DUMMY_CODING, NUMBER_OF_MQTT_PASSWORD_BIT);
    if (memcmp(Password, pPasswordIn, NUMBER_OF_MQTT_PASSWORD_BIT) == 0)
      return true;

    if (SetMqttPassword(pPasswordIn) == true)
      return true;
  }

  return false;
}

void ProtocolGetMqttSubscriptioTopic(void *pTopicOut)
{
  if (pTopicOut != NULL)
  {
    GetMqttSubscribeTopic(pTopicOut);
  }
}

bool ProtocolSetMqttSubscriptioTopic(const void *pTopicIn)
{
  char Topic[NUMBER_OF_MQTT_TOPIC_BIT] = {0};

  if (pTopicIn != NULL)
  {
    memset(Topic, PROTOCOL_DUMMY_CODING, NUMBER_OF_MQTT_TOPIC_BIT);
    if (memcmp(Topic, pTopicIn, NUMBER_OF_MQTT_TOPIC_BIT) == 0)
      return true;

    if (SetMqttSubscribeTopic(pTopicIn) == true)
      return true;
  }

  return false;
}

void ProtocolGetMqttPublishTopic(void *pTopicOut)
{
  if (pTopicOut != NULL)
  {
    GetMqttPublishTopic(pTopicOut);
  }
}

bool ProtocolSetMqttPublishTopic(const void *pTopicIn)
{
  char Topic[NUMBER_OF_MQTT_TOPIC_BIT] = {0};

  if (pTopicIn != NULL)
  {
    memset(Topic, PROTOCOL_DUMMY_CODING, NUMBER_OF_MQTT_TOPIC_BIT);
    if (memcmp(Topic, pTopicIn, NUMBER_OF_MQTT_TOPIC_BIT) == 0)
      return true;

    if (SetMqttPublishTopic(pTopicIn) == true)
      return true;
  }

  return false;
}

void ProtocolGetTargetServerConnectionIpAddress(void *pAddressOut)
{
  if (pAddressOut != NULL)
  {
    GetServerConnectAddress(pAddressOut);
  }
}

bool ProtocolSetTargetServerConnectionIpAddress(const void *pAddressIn)
{
  char Address[NUMBER_OF_SERVER_IP_ADDRESS] = {0};

  if (pAddressIn != NULL)
  {
    memset(Address, PROTOCOL_DUMMY_CODING, NUMBER_OF_SERVER_IP_ADDRESS);
    if (memcmp(Address, pAddressIn, NUMBER_OF_SERVER_IP_ADDRESS) == 0)
      return true;

    if (SetServerConnectAddress(pAddressIn) == true)
      return true;
  }

  return false;
}

uint8_t ProtocolGetWirelessModuleEmissionPower(void)
{
  return GetWirelessModuleEmissionPower();
}

bool ProtocolSetWirelessModuleEmissionPower(uint8_t EmissionPower)
{
  if (EmissionPower == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetWirelessModuleEmissionPower(EmissionPower) == true)
    return true;

  return false;
}

uint8_t ProtocolGetWirelessModuleNetworkTimeout(void)
{
  return GetWirelessModuleSearchNetworkTimeout();
}

bool ProtocolSetWirelessModuleNetworkTimeout(uint8_t NetworkTimeout)
{
  if (NetworkTimeout == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetWirelessModuleNetworkTimeout(NetworkTimeout) == true)
    return true;

  return false;
}

uint8_t ProtocolGetWirelessModuleFrequencyRange(void)
{
  return GetWirelessModuleFrequencyRange();
}

bool ProtocolSetWirelessModuleFrequencyRange(uint8_t FrequencyRange)
{
  if (FrequencyRange == PROTOCOL_ENQUIRY_FLAG)
    return true;

  if (SetWirelessModuleFrequencyRange(FrequencyRange) == true)
    return true;

  return false;
}

void ProtocolLoadDeviceParametersFromMemory(void)
{
  MemoryLoadDeviceParametersFromMemory();
}

void ProtocolUpdateDeviceParamete(void)
{
  MemoryUpdateDeviceParameters();
}

bool ProtocolExecuteCommandToUnlock(const uint8_t *pUserIdIn, uint8_t Mode)
{
  uint8_t UnlockType = 0;

  switch (Mode)
  {
  case DOOR_UNLOCK:
    UnlockType = DOOR_ACTION_UNLOCK;
    break;

  case DOOR_NORMAL_OPEN:
    UnlockType = DOOR_ACTION_NORMAL_OPEN;
    break;

  default:
    UnlockType = DOOR_ACTION_LOCK;
    break;
  }

  return EventExecuteUnlockTask(LOG_COMMAND_OPEN_DOOR, pUserIdIn, 0, UnlockType);
}

void ProtocolExecuteQrCodeToUnLock(const uint8_t *pUserIdIn)
{
  EventExecuteUnlockTask(LOG_QR_CODE_SCANF, pUserIdIn, 0, DOOR_ACTION_UNLOCK);
}

void ProtocolExternalHostRequestToUnlock(uint8_t KeyType, const uint8_t *pKeyValueIn)
{
  uint8_t ConvertedUnlockingType = 0;

  switch (KeyType)
  {
  case CARD_AUTHENTICATION:
    ConvertedUnlockingType = LOG_PHYSICAL_CARD_NUMBER;
    break;

  case PASSWORD_AUTHENTICATION:
    ConvertedUnlockingType = LOG_USER_KEYSCANF_PASSWORD;
    break;

  case QRCODE_AUTHENTICATION:
    ConvertedUnlockingType = LOG_QR_CODE_SCANF;
    break;

  case FINGER_PRINTF_AUTHENTICATION:
    ConvertedUnlockingType = LOG_FINGER_SCANF;
    break;

  case FACE_ID_AUTHENTICATION:
    ConvertedUnlockingType = LOG_FACE_SCANF;
    break;

  case COMMAND_REMOTE_AUTHENTICATION:
    ConvertedUnlockingType = LOG_COMMAND_OPEN_DOOR;
    break;

  case BLUETOOTH_VIRTUAL_CARD_AUTHENTICATION:
    ConvertedUnlockingType = LOG_BLUETOOTH_VIRTUAL_CARD_NUMBER;
    break;

  default:
    ConvertedUnlockingType = PROTOCOL_DUMMY_CODING;
    break;
  }

  EventExecuteUnlockTask(KeyType, pKeyValueIn, 0, DOOR_ACTION_UNLOCK);
}

void ProtocolPromptForDeviceActivation(void)
{
  PlayDeviceActivatedAudio();
}

void ProtocolPlayConnectTestAudio(void)
{
  PlayConnectTestAudio();
  PromptConnectTest();
}

void ProtocolSendDataToBluetoothHost(const void *pDataIn, uint16_t SizeIn)
{
  BluetoothSendDataToHost(pDataIn, SizeIn);
}

void ProtocolSendDataToNetwok(const uint8_t *pDataIn, uint16_t SizeIn)
{
#if _NETWOK_FUNCTION_ENABLE_
  NetworkPushMessageToHost(pDataIn, SizeIn);
#endif
}

uint16_t ProtocolGetNumberOfRegisterKeys(const uint8_t *pUserNameIn)
{
  return QueryTheNumberOfCorrespondingUserKeys(pUserNameIn);
}

bool ProtocolRWCardReplaceTime(uint8_t CardType, uint32_t *pCardReplaceTime, uint16_t *pCardReplaceId, bool Active)
{
  if ((pCardReplaceTime != NULL) && (pCardReplaceId != NULL))
  {
    if ((CardType == GUEST_CARD) || (CardType == MASTER_CARD) || (CardType == BUILD_CARD) || (CardType == FLOOR_CARD) || (CardType == PARK_CARD) || (CardType == NORMAL_OPEN_CARD))
    {
      if (Active == true)
      {
        uint16_t CardReplaceId = *pCardReplaceId;
        uint32_t CardReplaceTime = *pCardReplaceTime;

        switch (CardType)
        {
        case GUEST_CARD:
        {
          SetGuestCardReplaceId(CardReplaceId);
          SetGuestCardReplaceTime(CardReplaceTime);
        }
        break;

        case MASTER_CARD:
        {
          SetMasterCardReplaceId(CardReplaceId);
          SetMasterCardReplaceTime(CardReplaceTime);
        }
        break;

        case BUILD_CARD:
        {
          SetBuildCardReplaceId(CardReplaceId);
          SetBuildCardReplaceTime(CardReplaceTime);
        }
        break;

        case FLOOR_CARD:
        {
          SetFloorCardReplaceId(CardReplaceId);
          SetFloorCardReplaceTime(CardReplaceTime);
        }
        break;

        case PARK_CARD:
        {
          SetParkCardReplaceId(CardReplaceId);
          SetParkCardReplaceTime(CardReplaceTime);
        }
        break;

        case NORMAL_OPEN_CARD:
        {
          SetNormalOpenCardReplaceId(CardReplaceId);
          SetNormalOpenCardReplaceTime(CardReplaceTime);
        }
        break;
        }

        ProtocolUpdateDeviceParamete();
      }
      else
      {
        switch (CardType)
        {
        case GUEST_CARD:
        {
          *pCardReplaceId = GetGuestCardReplaceId();
          *pCardReplaceTime = GetGuestCardReplaceTime();
        }
        break;

        case MASTER_CARD:
        {
          *pCardReplaceId = GetMasterCardReplaceId();
          *pCardReplaceTime = GetMasterCardReplaceTime();
        }
        break;

        case BUILD_CARD:
        {
          *pCardReplaceId = GetBuildCardReplaceId();
          *pCardReplaceTime = GetBuildCardReplaceTime();
        }
        break;

        case FLOOR_CARD:
        {
          *pCardReplaceId = GetFloorCardReplaceId();
          *pCardReplaceTime = GetFloorCardReplaceTime();
        }
        break;

        case PARK_CARD:
        {
          *pCardReplaceId = GetParkCardReplaceId();
          *pCardReplaceTime = GetParkCardReplaceTime();
        }
        break;

        case NORMAL_OPEN_CARD:
        {
          *pCardReplaceId = GetNormalOpenCardReplaceId();
          *pCardReplaceTime = GetNormalOpenCardReplaceTime();
        }
        break;
        }
      }

      return true;
    }
  }

  return false;
}

uint8_t ProtocolGetNoDisturbingStartHour(void)
{
  return GetNoDisturbingStartHour();
}

bool ProtocolSetNoDisturbingStartHour(uint8_t StartHour)
{
  if (StartHour == PROTOCOL_DUMMY_CODING)
    return true;

  if (SetNoDisturbingStartHour(StartHour) == true)
    return true;

  return false;
}

uint8_t ProtocolGetNoDisturbingStartMinute(void)
{
  return GetNoDisturbingStartMinute();
}

bool ProtocolSetNoDisturbingStartMinute(uint8_t StartMinute)
{
  if (StartMinute == PROTOCOL_DUMMY_CODING)
    return true;

  if (SetNoDisturbingStartMinute(StartMinute) == true)
    return true;

  return false;
}

uint8_t ProtocolGetNoDisturbingEndHour(void)
{
  return GetNoDisturbingEndHour();
}

bool ProtocolSetNoDisturbingEndtHour(uint8_t EndHour)
{
  if (EndHour == PROTOCOL_DUMMY_CODING)
    return true;

  if (SetNoDisturbingEndHour(EndHour) == true)
    return true;

  return false;
}

uint8_t ProtocolGetNoDisturbingEndMinute(void)
{
  return GetNoDisturbingEndMinute();
}

bool ProtocolSetNoDisturbingEndMinute(uint8_t EndMinute)
{
  if (EndMinute == PROTOCOL_DUMMY_CODING)
    return true;

  if (SetNoDisturbingEndMinute(EndMinute) == true)
    return true;

  return false;
}

void ProtocolResetAccumulatedTimeOfHeartbeats(void)
{
  EventResetAccumulatedTimeOfGetServerMessage();
}

uint8_t ProtocolGetUserKeyInformation(const uint8_t UserId, const void *pUserNameIn, const uint8_t StartNumber, const uint8_t EndNumber, uint8_t *pCardHolderInformationOutOut, uint16_t *pInformationSizeOut)
{
  uint16_t AnswerDataLength = 0;
  uint8_t GetResult = OPERATION_FAILURE;
  CardholderInformation_t CardholderInformation = {0};

  if ((pUserNameIn != NULL) && (pCardHolderInformationOutOut != NULL))
  {
    GetResult = MESSAGE_ERROR_DELIVER_PARAM;

    if (EndNumber < MAX_NUMBER_OF_KEYS_CARRIED_BY_SINGLE_USER)
    {
      if (UserId != PROTOCOL_DUMMY_CODING)
      {
        if (ObtainingCardholderInformationForTargetCatalogue(UserId, &CardholderInformation) == true)
        {
          GetResult = MESSAGE_PRASE_SUCCESS;
        }
      }
      else
      {
        GetResult = USER_DOES_NOT_EXIST;

        if (GetUserKeyInformation(pUserNameIn, &CardholderInformation) == true)
        {
          GetResult = MESSAGE_PRASE_SUCCESS;
        }
      }
    }

    if (GetResult == MESSAGE_PRASE_SUCCESS)
    {
      memcpy(&pCardHolderInformationOutOut[AnswerDataLength], CardholderInformation.UserInformation.UserName, USER_NAME_LENGTH);
      AnswerDataLength += USER_NAME_LENGTH;
      pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.UserInformation.Status;
      pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.UserInformation.NumberOfKey;

      for (uint8_t i = StartNumber; i <= EndNumber; i++)
      {
        switch (CardholderInformation.KeyInformation[i].AuthenticationType)
        {
        case CARD_AUTHENTICATION:
        case FACE_ID_AUTHENTICATION:
        case PASSWORD_AUTHENTICATION:
        case FINGER_PRINTF_AUTHENTICATION:
        case BLUETOOTH_VIRTUAL_CARD_AUTHENTICATION:
        {
          pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].AuthenticationType;
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].KeyToken & 0xFF000000) >> 24);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].KeyToken & 0x00FF0000) >> 16);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].KeyToken & 0x0000FF00) >> 8);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)(CardholderInformation.KeyInformation[i].KeyToken & 0x000000FF);
          memcpy(&pCardHolderInformationOutOut[AnswerDataLength], CardholderInformation.KeyInformation[i].AuthenticationKey, USER_AUTHENTICATION_KEY_LENGTH);
          AnswerDataLength += USER_AUTHENTICATION_KEY_LENGTH;
          pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].Count;
          pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].Date;
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].StartTimestamp & 0xFF000000) >> 24);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].StartTimestamp & 0x00FF0000) >> 16);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].StartTimestamp & 0x0000FF00) >> 8);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)(CardholderInformation.KeyInformation[i].StartTimestamp & 0x000000FF);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].EndTimestamp & 0xFF000000) >> 24);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].EndTimestamp & 0x00FF0000) >> 16);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)((CardholderInformation.KeyInformation[i].EndTimestamp & 0x0000FF00) >> 8);
          pCardHolderInformationOutOut[AnswerDataLength++] = (uint8_t)(CardholderInformation.KeyInformation[i].EndTimestamp & 0x000000FF);
          for (uint8_t j = 0; j < MAX_TIME_SLOTS; j++)
          {
            pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].TimePeriod[j].TimeCycle.StartHour;
            pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].TimePeriod[j].TimeCycle.StartMinute;
            pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].TimePeriod[j].TimeCycle.EndHour;
            pCardHolderInformationOutOut[AnswerDataLength++] = CardholderInformation.KeyInformation[i].TimePeriod[j].TimeCycle.EndMinute;
          }
        }
        break;
        }
      }
    }
    else
    {
      memcpy(&pCardHolderInformationOutOut[AnswerDataLength], pUserNameIn, USER_NAME_LENGTH);
      AnswerDataLength += USER_NAME_LENGTH;
    }
  }

  if (pInformationSizeOut != NULL)
  {
    *pInformationSizeOut = AnswerDataLength;
  }

  return GetResult;
}

uint8_t ProtocolNewCardholder(const void *pInformationIn)
{
  NewCardholderFormat_t *pNewCardholderFormat = (NewCardholderFormat_t *)pInformationIn;

  if (pNewCardholderFormat != NULL)
  {
    KeyInformation_t KeyInformation = {0};
    KeyInformation.Date = pNewCardholderFormat->Date;
    KeyInformation.Count = pNewCardholderFormat->Count;
    KeyInformation.KeyToken = pNewCardholderFormat->KeyToken;
    KeyInformation.EndTimestamp = pNewCardholderFormat->EndTimestamp;
    KeyInformation.AuthenticationType = pNewCardholderFormat->KeyType;
    KeyInformation.StartTimestamp = pNewCardholderFormat->StartTimestamp;
    memcpy(KeyInformation.AuthenticationKey, pNewCardholderFormat->KeyValue, USER_AUTHENTICATION_KEY_LENGTH);
    for (uint8_t i = 0; i < MAX_TIME_SLOTS; i++)
    {
      KeyInformation.TimePeriod[i].TimeCycle.StartHour = pNewCardholderFormat->TimePeriod[i].StartHour;
      KeyInformation.TimePeriod[i].TimeCycle.StartMinute = pNewCardholderFormat->TimePeriod[i].StartMinute;
      KeyInformation.TimePeriod[i].TimeCycle.EndHour = pNewCardholderFormat->TimePeriod[i].EndHour;
      KeyInformation.TimePeriod[i].TimeCycle.EndMinute = pNewCardholderFormat->TimePeriod[i].EndMinute;
    }

    if ((pNewCardholderFormat->KeyType == CARD_AUTHENTICATION) || (pNewCardholderFormat->KeyType == PASSWORD_AUTHENTICATION))
    {
      if (((pNewCardholderFormat->Count >= MIX_NUMBER_OF_USE) && (pNewCardholderFormat->Count <= MAX_NUMBER_OF_USE)) || (pNewCardholderFormat->Count == USE_UNLIMITED_TIMES))
      {
        CardholderCommandResult_t Result = NewCardholders(pNewCardholderFormat->UserName, &KeyInformation);
        switch (Result)
        {
        case UNKNOWN_KEY_TYPE:
          return MESSAGE_ERROR_DELIVER_PARAM;

        case KEY_ALREADY_EXISTS:
          return CARDHOLDER_ALREADY_EXISTS;

        case RECORD_SUCCESSFULLY:
          return MESSAGE_PRASE_SUCCESS;

        case OVER_OF_SINGLE_USER_REGISTER_KEY:
          return OVER_OF_SINGLE_USER_REGISTER;

        case CARD_HOLDER_FULL:
          return EXCEED_USER_LIMIT;

        default:
          break;
        }
      }
    }

    return MESSAGE_ERROR_DELIVER_PARAM;
  }

  return OPERATION_FAILURE;
}

uint8_t ProtocolDeleteCardholder(const void *pInformationIn)
{
  DeleteCardholderFormat_t *pDeleteCardholderFormat = (DeleteCardholderFormat_t *)pInformationIn;

  if (pDeleteCardholderFormat != NULL)
  {
    CardholderCommandResult_t Result = DeleteCardholders(pDeleteCardholderFormat->KeyType, pDeleteCardholderFormat->UserName, pDeleteCardholderFormat->KeyValue);
    switch (Result)
    {
    case UNKNOWN_KEY_TYPE:
      return MESSAGE_ERROR_DELIVER_PARAM;

    case DELETED_SUCCESSFULLY:
      return MESSAGE_PRASE_SUCCESS;

    case USER_NO_FOUND:
      return USER_DOES_NOT_EXIST;

    default:
      break;
    }
  }

  return OPERATION_FAILURE;
}

uint8_t ProtocolUpdateCardholder(const void *pInformationIn)
{
  UpdateCardholderFormat_t *pUpdateCardholderFormat = (UpdateCardholderFormat_t *)pInformationIn;

  if (pUpdateCardholderFormat != NULL)
  {
    if (pUpdateCardholderFormat->EndTimestamp >= pUpdateCardholderFormat->StartTimestamp)
    {
      if ((pUpdateCardholderFormat->UserStatus == NORMAL_USE) || (pUpdateCardholderFormat->UserStatus == BLACKLIST_KEY) || (pUpdateCardholderFormat->UserStatus == USE_UNLIMITED_TIMES))
      {
        if (((pUpdateCardholderFormat->Count >= MIX_NUMBER_OF_USE) && (pUpdateCardholderFormat->Count <= MAX_NUMBER_OF_USE)) || (pUpdateCardholderFormat->Count == USE_UNLIMITED_TIMES))
        {
          KeyInformation_t KeyInformation = {0};

          KeyInformation.Date = pUpdateCardholderFormat->Date;
          KeyInformation.Count = pUpdateCardholderFormat->Count;
          KeyInformation.EndTimestamp = pUpdateCardholderFormat->EndTimestamp;
          KeyInformation.AuthenticationType = pUpdateCardholderFormat->KeyType;
          KeyInformation.StartTimestamp = pUpdateCardholderFormat->StartTimestamp;
          memcpy(KeyInformation.AuthenticationKey, pUpdateCardholderFormat->KeyValue, USER_AUTHENTICATION_KEY_LENGTH);
          for (uint8_t i = 0; i < MAX_TIME_SLOTS; i++)
          {
            KeyInformation.TimePeriod[i].TimeCycle.StartHour = pUpdateCardholderFormat->TimePeriod[i].StartHour;
            KeyInformation.TimePeriod[i].TimeCycle.StartMinute = pUpdateCardholderFormat->TimePeriod[i].StartMinute;
            KeyInformation.TimePeriod[i].TimeCycle.EndHour = pUpdateCardholderFormat->TimePeriod[i].EndHour;
            KeyInformation.TimePeriod[i].TimeCycle.EndMinute = pUpdateCardholderFormat->TimePeriod[i].EndMinute;
          }

          CardholderCommandResult_t Result = ModifyCardholderInformation(pUpdateCardholderFormat->UserName, pUpdateCardholderFormat->UserStatus, &KeyInformation);
          switch (Result)
          {
          case USER_NO_FOUND:
            return USER_DOES_NOT_EXIST;

          case RECORD_SUCCESSFULLY:
            return MESSAGE_PRASE_SUCCESS;

          default:
            return OPERATION_FAILURE;
          }
        }
      }
    }

    return MESSAGE_ERROR_DELIVER_PARAM;
  }

  return OPERATION_FAILURE;
}

uint8_t ProtocolGetRegisteredCardholderList(uint8_t *pCardholderListOut)
{
  return GetRegisteredCardholderSerialNumber(pCardholderListOut);
}

uint8_t ProtocolAnalyzingBluetoothVirtualCards(const void *pMessageIn)
{
  KeyInformation_t CardInformation = {0};
  uint8_t PraseResult = OPERATION_FAILURE;
  BluetoothVirtualCardFormat_t *pBluetoothVirtualCard = (BluetoothVirtualCardFormat_t *)pMessageIn;

  if (pMessageIn != NULL)
  {
    {
      CardInformation.Count = USE_UNLIMITED_TIMES;
      CardInformation.Date = pBluetoothVirtualCard->Date;
      CardInformation.EndTimestamp = pBluetoothVirtualCard->EndTimestamp;
      CardInformation.KeyToken = pBluetoothVirtualCard->AuthorizationCode;
      CardInformation.StartTimestamp = pBluetoothVirtualCard->StartTimestamp;
      CardInformation.AuthenticationType = BLUETOOTH_VIRTUAL_CARD_AUTHENTICATION;
      memcpy(CardInformation.AuthenticationKey, pBluetoothVirtualCard->KeyValue, USER_AUTHENTICATION_KEY_LENGTH);
      for (uint8_t i = 0; i < MAX_TIME_SLOTS; i++)
      {
        CardInformation.TimePeriod[i].TimeCycle.StartHour = pBluetoothVirtualCard->TimePeriod[i].StartHour;
        CardInformation.TimePeriod[i].TimeCycle.StartMinute = pBluetoothVirtualCard->TimePeriod[i].StartHour;
        CardInformation.TimePeriod[i].TimeCycle.EndHour = pBluetoothVirtualCard->TimePeriod[i].EndHour;
        CardInformation.TimePeriod[i].TimeCycle.EndMinute = pBluetoothVirtualCard->TimePeriod[i].EndMinute;
      }
    }

    {
      CardholderCommandResult_t Result = BluetoothVirtualCardAuthentication(pBluetoothVirtualCard->UserName, pBluetoothVirtualCard->CreationTime, &CardInformation);
      switch (Result)
      {
      case AUTHENTICATION_SUCCESS:
      {
        PraseResult = TARGET_DEVICE_BUSY;
        if (EventExecuteUnlockTask(LOG_BLUETOOTH_VIRTUAL_CARD_NUMBER, CardInformation.AuthenticationKey, CardInformation.EndTimestamp, DOOR_ACTION_UNLOCK) == true)
        {
          PraseResult = MESSAGE_PRASE_SUCCESS;
        }
      }
      break;

      case CARD_HOLDER_FULL:
      {
        PraseResult = EXCEED_USER_LIMIT;
        EventCardholderAuthenticationError(KEY_TYPE_BLUETOOTH_VIRTUAL_CARD);
      }
      break;

      case AUTHENTICATION_FAILURE:
      {
        PraseResult = PERMISSION_DENIED;
        EventCardholderAuthenticationError(KEY_TYPE_BLUETOOTH_VIRTUAL_CARD);
      }
      break;

      case NOT_IN_THE_ALLOWED_TIME:
      {
        PraseResult = PERMISSION_DENIED;
        EventCardholderOutOfDate(KEY_TYPE_BLUETOOTH_VIRTUAL_CARD);
      }
      break;

      case OVER_OF_SINGLE_USER_REGISTER_KEY:
      {
        PraseResult = OVER_OF_SINGLE_USER_REGISTER;
        EventCardholderAuthenticationError(KEY_TYPE_BLUETOOTH_VIRTUAL_CARD);
      }
      break;

      default:
      {
        PraseResult = OPERATION_FAILURE;
        EventCardholderAuthenticationError(KEY_TYPE_BLUETOOTH_VIRTUAL_CARD);
      }
      break;
      }
    }
  }

  return PraseResult;
}

uint32_t ProtocolGetUpdateBootloaderFirmwareCrcValue(uint32_t FileSize)
{
  return GetBackupBootloaderFirmwareCheckCode(FileSize);
}

bool ProtocolWriteBootloaderFirmwareData(uint32_t WriteOffset, const uint8_t *pFileDataIn, uint32_t FileSize)
{
  return WriteBackupBootloaderFirmwareData(WriteOffset, pFileDataIn, FileSize);
}

bool ProtocolStartDeviceSelfTestTask(void)
{
  EventStartDeviceSelfTestTask();
  return true;
}

uint8_t ProtocolGetSafetyModuleNumberOfRegisteredUsers(void)
{
  return SafetyGetTheNumberOfUsers();
}

void ProtocolGetSafetyModuleSerialNumber(char *pSerialNumberOut)
{
  SafetyGetTheModuleSerialNumber(pSerialNumberOut);
}

void ProtocolGetSafetyModuleApplicationVersion(char *pVersionOut)
{
  SafetyGetTheModuleApplicationVersion(pVersionOut);
}

void ProtocolGetSafetyModuleAlgorithmVersion(char *pVersionOut)
{
  SafetyGetTheModuleAlgorithmVersion(pVersionOut);
}

uint8_t ProtocolGetWirelessCommunicationQuality(void)
{
  uint8_t WirelessQuality = 0;

#if _NETWOK_FUNCTION_ENABLE_

#if _NETWOK_MODLE_TYPE_ == _TP1107_MODULE_
  WirelessQuality = Tp1107GetWirelessQuality();
#elif _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
  WirelessQuality = Ml307GetSignalStrength();
#endif

#endif

  return WirelessQuality;
}

void ProtocolGetWirelessModuleSerialNumber(void *pSerialNumberOut)
{
#if _NETWOK_FUNCTION_ENABLE_

#if _NETWOK_MODLE_TYPE_ == _TP1107_MODULE_
  Tp1107GetSerialNumber(pSerialNumberOut);
#elif _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
  Ml307GetImeiCode(pSerialNumberOut);
#endif

#endif
}

void ProtocolGetWirelessModuleApplication(void *pApplicationOut)
{
#if _NETWOK_FUNCTION_ENABLE_

#if _NETWOK_MODLE_TYPE_ == _TP1107_MODULE_
  Tp1107GetFirmwareVersionNumber(pApplicationOut);
#elif _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
  Ml307GetFirmwareVersion(pApplicationOut);
#endif

#endif
}

void ProtocolGetWirelessSimCardNumber(char *pSimCardOut)
{
#if _NETWOK_FUNCTION_ENABLE_

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
  Ml307GetSimIccidCode(pSimCardOut);
#endif

#endif
}

void ProtocolGetWirelessImsiCode(char *pImsiOut)
{
#if _NETWOK_FUNCTION_ENABLE_

#if _NETWOK_MODLE_TYPE_ == _ML307R_MODLE_
  Ml307GetImsiCode(pImsiOut);
#endif

#endif
}

void ProtocolRemindersKeyOperationSuccess(void)
{
  PromptKeyOperationSuccess();
}

void ProtocolRemindersKeyOperationError(void)
{
  PromptKeyOperationError();
}

void ProtocolPromptToNetworkAttachmentFailure(void)
{
  if (EventExitPushOnlineRegisterStatusTask(SEND_STATUS_ERROR) == true)
    return;

  if (EventExitAlarmReportingTask(SEND_STATUS_ERROR) == true)
    return;

  if (EventExitInformationReportingTask(SEND_STATUS_ERROR) == true)
    return;

  if (EventExitRequestServerInformationTask(SEND_STATUS_ERROR) == true)
    return;

  if (EventExitActivelyRequestServerTask(SEND_STATUS_ERROR) == true)
    return;
}

void ProtocolPromptToNetworkAttachmentEnd(void)
{
  if (EventExitPushOnlineRegisterStatusTask(SEND_STATUS_DONE) == true)
    return;

  if (EventExitAlarmReportingTask(SEND_STATUS_DONE) == true)
    return;

  if (EventExitInformationReportingTask(SEND_STATUS_DONE) == true)
    return;

  if (EventExitRequestServerInformationTask(SEND_STATUS_DONE) == true)
    return;

  if (EventExitActivelyRequestServerTask(SEND_STATUS_DONE) == true)
    return;
}

void ProtocolRemindersConnectionAnomaly(void)
{
  if (EventExitPushOnlineRegisterStatusTask(SEND_STATUS_HOST_NO_ACK) == true)
    return;

  if (EventExitAlarmReportingTask(SEND_STATUS_HOST_NO_ACK) == true)
    return;

  if (EventExitInformationReportingTask(SEND_STATUS_HOST_NO_ACK) == true)
    return;

  if (EventExitRequestServerInformationTask(SEND_STATUS_HOST_NO_ACK) == true)
    return;

  if (EventExitActivelyRequestServerTask(SEND_STATUS_HOST_NO_ACK) == true)
    return;
}

void ProtocolCalculateAesEcbEncrypt(uint8_t *pKeyIn, uint8_t *pDataIn)
{
  LL_Encrypt(pKeyIn, pDataIn, pDataIn);
}

void ProtocolCalculateAesEcbDecrypt(uint8_t *pKeyIn, uint8_t *pDataIn)
{
  LL_Decrypt(pKeyIn, pDataIn, pDataIn);
}

void ProtocolRemindersCommandUnlockFailure(void)
{
  EventCardholderAuthenticationError(KEY_TYPE_COMMAND_REMOTE);
}

void ProtocolRemindersQrcodeUnlockFailure(void)
{
  EventCardholderAuthenticationError(KEY_TYPE_QRCODE);
}

void ProtocolRemindersInsufficientAuthority(uint8_t KeyType)
{
  EventCardholderAuthenticationError(KeyType);
}

bool ProtocolStartDeviceRebootTask(void)
{
  return EventStartDeviceRebootTask();
}

bool ProtocolStartDeviceFactoryResetTask(void)
{
  EventStartFactorySettingTask();
  return true;
}

void ProtocolMarkDeviceIntoStandbyMode(void)
{
  EventNetworkKeepLiveTimerConfig(true);
  EventResetAccumulatedTimeOfNetworkKeepLive();
}

void ProtocolResetNetworkKeepLiveTimer(void)
{
  if (EventGetNetworkKeepLiveTimerConfigEn() == true)
  {
    EventResetAccumulatedTimeOfNetworkKeepLive();
  }
}

void ProtocolMarkLogUploadFinished(void)
{
  EventSetStatusUpdateFlagBit(true);
  EventSetLogNeedToBeUploadedFlagBit(false);
}

bool ProtocolStartActivelyRequestServerTask(void)
{
  return EventStartActivelyRequestServerTask();
}

bool ProtocolStartNetworkAttachmentTask(void)
{
  return NetworkInitiateNetworkAttachmentTask();
}

bool ProtocolStartSafetyFeatureValueFileRegistration(void)
{
  return SafetyStartRegisteringUsersByFeatureValueTask();
}

bool ProtocolStartLocalRegisterKeyTask(const void *pLocalRegistrationInformationIn)
{
  LocalRegistrationFormat_t *pLocalRegistrationInformation = (LocalRegistrationFormat_t *)pLocalRegistrationInformationIn;

  if (pLocalRegistrationInformation != NULL)
  {
    RegisterKeyInformation_t RegisterKeyInformation = {0};

    RegisterKeyInformation.Count = pLocalRegistrationInformation->Count;
    RegisterKeyInformation.KeyToken = pLocalRegistrationInformation->KeyToken;
    RegisterKeyInformation.AuthenticationType = pLocalRegistrationInformation->KeyType;
    memset(RegisterKeyInformation.AuthenticationKey, 0, USER_AUTHENTICATION_KEY_LENGTH);
    memcpy(RegisterKeyInformation.UserName, pLocalRegistrationInformation->UserName, USER_NAME_LENGTH);

    RegisterKeyInformation.Date = pLocalRegistrationInformation->Date;
    RegisterKeyInformation.EndTimestamp = pLocalRegistrationInformation->EndTimestamp;
    RegisterKeyInformation.StartTimestamp = pLocalRegistrationInformation->StartTimestamp;
    for (uint8_t i = 0; i < MAX_TIME_SLOTS; i++)
    {
      RegisterKeyInformation.StartHour[i] = pLocalRegistrationInformation->TimePeriod[i].StartHour;
      RegisterKeyInformation.StartMinute[i] = pLocalRegistrationInformation->TimePeriod[i].StartMinute;
      RegisterKeyInformation.EndHour[i] = pLocalRegistrationInformation->TimePeriod[i].EndHour;
      RegisterKeyInformation.EndMinute[i] = pLocalRegistrationInformation->TimePeriod[i].EndMinute;
    }

    if (EventStartLocalRegisterKeyTask(&RegisterKeyInformation) == true)
    {
      EventSetLocalRegisterKeyStep(LOCAL_REGISTER_WAIT_TIGGER);
      EventUpdateLocalRegisterKeyResult(LOCAL_REGISTER_RESULT_IDLE);
      return true;
    }
  }

  return false;
}

void ProtocolReadTheEigenvalueFileInformation(uint32_t *pFileSizeOut, uint8_t *pCheckCodeOut)
{
  OnlineRegisterInformation_t RegisterInformation = {0};

  if (EventGetOnlineRegisterKeyInformation(&RegisterInformation) == true)
  {
    if (pFileSizeOut != NULL)
    {
      *pFileSizeOut = RegisterInformation.FileSize;
    }

    if (pCheckCodeOut != NULL)
    {
      *pCheckCodeOut = RegisterInformation.CheckCode;
    }
  }
}

bool ProtocolSaveTheEigenvalueFile(uint32_t Offset, const void *pDataIn, uint16_t FileSize)
{
  return WriteToTemporaryFile(Offset, pDataIn, FileSize);
}

void ProtocolResetBootloaderFirmwareTaskTimer(void)
{
  EventResetTheRunningTimeOfSpecificAction(DEV_BOOTLOADER_UPDATA);
}

bool ProtocolIntoBootloaderFirmwareUpdate(uint32_t FileSize)
{
  if ((FileSize > 0) && (FileSize <= GetTotalBootloaderFirmwareFileSize()))
    return true;

  return false;
}

bool ProtocolWriteIoBoardFirmwareFile(uint32_t Offset, const void *pDataIn, uint16_t FileSize)
{
  return FlashWriteIoBoardFirmware(Offset, pDataIn, FileSize);
}

void ProtocolReadIoBoardFirmwareFile(uint32_t Offset, void *pDataOut, uint16_t FileSize)
{
  FlashReadIoBoardFirmware(Offset, pDataOut, FileSize);
}

bool ProtocolIntoFirmwareUpdate(uint32_t FileSize)
{
  if ((FileSize > 0) && (FileSize <= APPLICATION_ACTUAL_OCCUPIED_SPACE))
    return true;

  return false;
}

uint16_t ProtocolGetNumberOfLofFile(void)
{
  return GetLogStackDepth();
}

void ProtocolWriteCommandUnlockExecuteResultLog(uint8_t *pUserIdIn, bool Result)
{
  CardHolderVerifyStatus_t VerifyStatus = (Result != true) ? CARDHOLDER_AUTHECTICATION_ERROR : CARDHOLDER_AUTHENTICATION_SUCCESS;
  MemoryWriteUnlockLogMessage(LOG_COMMAND_OPEN_DOOR, pUserIdIn, VerifyStatus);
}

void ProtocolWriteQrUnlockExecuteResultLog(uint8_t *pUserIdIn, bool Result)
{
  CardHolderVerifyStatus_t VerifyStatus = (Result != true) ? CARDHOLDER_AUTHECTICATION_ERROR : CARDHOLDER_AUTHENTICATION_SUCCESS;
  MemoryWriteUnlockLogMessage(LOG_QR_CODE_SCANF, pUserIdIn, VerifyStatus);
}

void ProtocolWriteExternalValidationResultLog(uint8_t KeyType, uint8_t *pKeyValueIn, bool Result)
{
  uint8_t TpranslatedKeyType = 0;
  CardHolderVerifyStatus_t VerifyStatus = (Result != true) ? CARDHOLDER_AUTHECTICATION_ERROR : CARDHOLDER_AUTHENTICATION_SUCCESS;

  switch (KeyType)
  {
  case CARD_AUTHENTICATION:
    TpranslatedKeyType = LOG_PHYSICAL_CARD_NUMBER;
    break;

  case PASSWORD_AUTHENTICATION:
    TpranslatedKeyType = LOG_USER_KEYSCANF_PASSWORD;
    break;

  case FINGER_PRINTF_AUTHENTICATION:
    TpranslatedKeyType = LOG_FINGER_SCANF;
    break;

  case FACE_ID_AUTHENTICATION:
    TpranslatedKeyType = LOG_FACE_SCANF;
    break;

  case QRCODE_AUTHENTICATION:
    TpranslatedKeyType = LOG_QR_CODE_SCANF;
    break;

  default:
    break;
  }

  MemoryWriteUnlockLogMessage(TpranslatedKeyType, pKeyValueIn, VerifyStatus);
}

uint8_t ProtocolGetSpecificNumberOfLogFilesFromTheTargetSerialNumber(uint16_t SpecificNumber, uint8_t Quantity, uint8_t *pLogFileOut, uint16_t *pLogFileSizeOut)
{
  uint16_t LogFileSize = 0;
  LogDataSheet_t LogDataSheet = {0};

  if ((pLogFileOut != NULL) && (pLogFileSizeOut != NULL))
  {
    if ((Quantity > 0) && (Quantity <= MAX_NUMBER_OF_LOG_TABLE_GET))
    {
      if ((SpecificNumber + Quantity) <= LOG_LIMIT)
      {
        for (uint8_t i = 0; i < Quantity; i++)
        {
          GetLogFileInformationForTheTargetCode(SpecificNumber + i, &LogDataSheet);

          pLogFileOut[LogFileSize++] = LogDataSheet.EventType;
          pLogFileOut[LogFileSize++] = LogDataSheet.AttachParam;
          memcpy(&pLogFileOut[LogFileSize], LogDataSheet.Time, PROTOCOL_TIMESTAMP_BIT_LENGTH);
          LogFileSize += PROTOCOL_TIMESTAMP_BIT_LENGTH;
          memcpy(&pLogFileOut[LogFileSize], LogDataSheet.DataPacket, LOG_DATA_PACKET_LENGTH);
          LogFileSize += LOG_DATA_PACKET_LENGTH;
        }

        *pLogFileSizeOut = LogFileSize;
        return MESSAGE_PRASE_SUCCESS;
      }
    }
  }

  return MESSAGE_ERROR_DELIVER_PARAM;
}

void ProtocolGetCecheLogFilePacket(uint8_t *pLogFileOut, uint16_t *pLogFileSizeOut, uint8_t *pQuantityOut)
{
  if ((pLogFileOut != NULL) && (pLogFileSizeOut != NULL) && (pQuantityOut != NULL))
  {
    uint8_t LogQuantity = 0;
    uint16_t LogFileSize = 0;
    LogDataSheet_t LogDataSheet = {0};

    for (uint8_t i = 0; i < LOG_SINGLE_LOG_RETRIEVAL_LIMIT; i++)
    {
      bool LogCacheEn = GetLogCodesToBePushed(&LogDataSheet);
      if (LogCacheEn != true)
        break;

      pLogFileOut[LogFileSize++] = LogDataSheet.EventType;
      pLogFileOut[LogFileSize++] = LogDataSheet.AttachParam;
      memcpy(&pLogFileOut[LogFileSize], LogDataSheet.Time, PROTOCOL_TIMESTAMP_BIT_LENGTH);
      LogFileSize += PROTOCOL_TIMESTAMP_BIT_LENGTH;
      memcpy(&pLogFileOut[LogFileSize], LogDataSheet.DataPacket, LOG_DATA_PACKET_LENGTH);
      LogFileSize += LOG_DATA_PACKET_LENGTH;

      LogQuantity++;
    }

    *pQuantityOut = LogQuantity;
    *pLogFileSizeOut = LogFileSize;
  }
}

bool ProtocolGetLogFilePushStatus(void)
{
  return EventGetLogNeedToBeUploadedFlagBit();
}

void ProtocolUpdateLogFilePushStatus(uint16_t LogId)
{
  UpdateLogFilePushStatus(LogId);
}

uint8_t *ProtocolMessageMalloc(const uint16_t MallocSize)
{
  return tmos_msg_allocate(MallocSize);
}

void ProtocolMessageFree(void *ptr)
{
  tmos_msg_deallocate((uint8_t *)ptr);
}

uint32_t ProtocolMessageGetSystemClockTime(void)
{
  return RTC_GetCycle32k();
}

bool ProtocolThrowingEvent(uint8_t DataSource, const uint8_t *pMessageIn, const uint16_t SizeIn)
{
  if (pMessageIn != NULL)
  {
    if ((SizeIn > 0) && (SizeIn <= NOMINAL_PACKET_LENGTH))
    {
      if (pMessageIn[0] == PROTOCOL_SYNCWORD_CODE)
      {
        ProtocolRxMessageFormat_t *pRxMessageFormat = (ProtocolRxMessageFormat_t *)tmos_msg_allocate(sizeof(ProtocolRxMessageFormat_t));
        if (pRxMessageFormat != NULL)
        {
          memset(pRxMessageFormat, 0, sizeof(ProtocolRxMessageFormat_t));

          pRxMessageFormat->SizeOfData = SizeIn;
          pRxMessageFormat->DataSource = DataSource;
          memcpy(pRxMessageFormat->AttachedData, pMessageIn, SizeIn);
          if (tmos_msg_send(ProtocolCenterTaskHandle, (uint8_t *)pRxMessageFormat) == SUCCESS)
            return true;
        }
      }
    }
  }

  return false;
}

bool EventElevatorIoBoradFirmwareTransferTask(IoBoardFirmwareInfo_t *Parm)
{
  if (Parm != NULL)
  {
    // Rs485BitStatus.StepsOfSending = 0;
    ClearRs485BitStatus();
    ElevatorIoBoradFirmwareTransferTask(Parm);
    return true;
  }
  return false;
}

void ProtocolCenterStopSendingTask(void)
{
  tmos_stop_task(ProtocolCenterTaskHandle, MESSAGE_CENTER_SENDING);
}

void ProtocolDelayedStartSendingTask(uint32_t Ms)
{
  tmos_stop_task(ProtocolCenterTaskHandle, MESSAGE_CENTER_SENDING);
  tmos_start_task(ProtocolCenterTaskHandle, MESSAGE_CENTER_SENDING, MS1_TO_SYSTEM_TIME(Ms));
}

void ProtocolStartSendingTaskNoWait(void)
{
  tmos_stop_task(ProtocolCenterTaskHandle, MESSAGE_CENTER_SENDING);
  tmos_set_event(ProtocolCenterTaskHandle, MESSAGE_CENTER_SENDING);
}

void ProtocolCenterInitialisation(ProtocolCenterExternalInterfaces_t *pExternalInterfaces)
{
  ProtocolCenterExternalInterfaces.ProtocolSendingTask = pExternalInterfaces->ProtocolSendingTask;
  ProtocolCenterExternalInterfaces.ProtocolParsingTask = pExternalInterfaces->ProtocolParsingTask;

  ProtocolCenterTaskHandle = TMOS_ProcessEventRegister(ProtocolCenterTaskCallback);
}
